package nm.util.alarmclock;

import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.JFileChooser;
import javax.swing.Timer;
import java.io.File;
import java.net.URL;
import java.util.Calendar;
import java.applet.AudioClip;
import java.applet.Applet;
import java.text.DateFormat;

/**
 *  Copyright 2006 Nathan Middleton 
 *  
 *  Licensed under the Apache License, Version 2.0 (the "License"); you may not 
 *  use this file except in compliance with the License. You may obtain a copy 
 *  of the License at 
 *  
 *  	http://www.apache.org/licenses/LICENSE-2.0 Unless required
 *  
 *  by applicable law or agreed to in writing, software distributed under the 
 *  License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 
 *  OF ANY KIND, either express or implied. See the License for the specific 
 *  language governing permissions and limitations under the License.
 *  
 * @author Nathan Middleton
 */
public class AlarmClock implements ActionListener {
	public static final String CMD_OPTIONS = "OPTIONS";
	public static final String CMD_START = "START";
	public static final String CMD_STOP = "STOP";
	public static final String CMD_QUIT = "QUIT";
	public static final String CMD_ALARM = "ALARM";
	public static final String CMD_CHOOSE = "CHOOSE";
	public static final String STATUS_STOP = "Not Running.";
	public static final String STATUS_START = "Set for: ";
	public static final int STATE_STOPPED = 1;
	public static final int STATE_RUNNING = 2;
	
	public AlarmClock() {
		state = AlarmClock.STATE_STOPPED;
		alarm = null;
		clip = null;
		options = new AlarmOptions(this);
		menu = new AlarmMenu(this);
		icon = new AlarmIcon(AlarmClock.STATUS_STOP, menu, this);
		new AlarmTray(icon);
	}
	
	public void actionPerformed(ActionEvent event) {
		String cmd = event.getActionCommand();
		
		if( cmd.equals(AlarmClock.CMD_QUIT) )
		{
			switch(state) {
			case AlarmClock.STATE_RUNNING:
				if(alarm != null) alarm.stop();
				
			default:
				options.getSettings().save();
				System.exit(0);
			}
		}
		else if( cmd.equals(AlarmClock.CMD_OPTIONS) )
		{
			options.toggleSettings();
		}
		else if( cmd.equals(AlarmClock.CMD_START) )
		{
			switch(state) {
			case AlarmClock.STATE_RUNNING:
				if(alarm != null) alarm.stop();
				
			default:
				state = AlarmClock.STATE_RUNNING;
				options.getSettings().save();

				Calendar c = Calendar.getInstance();
				int hour = options.getSettings().getHour();
				int minute = options.getSettings().getMinute();
				int shift = 0;
				
				if(hour <= c.get(Calendar.HOUR_OF_DAY))
				{
					shift = 24 - Math.abs(hour - c.get(Calendar.HOUR_OF_DAY));
				}
				else if(hour > c.get(Calendar.HOUR_OF_DAY))
				{
					shift = hour - c.get(Calendar.HOUR_OF_DAY);
				}
				else 
				{
					// shouldn't get here
				}
				
				c.set(Calendar.SECOND, 0);
				c.set(Calendar.MINUTE, 0);
				c.add(Calendar.HOUR_OF_DAY, shift);
				c.add(Calendar.MINUTE, minute);

				icon.setToolTip(
						DateFormat.getDateTimeInstance().format(c.getTime()));
				icon.setImage(AlarmIcon.getIcon(
						c.get(Calendar.HOUR), c.get(Calendar.MINUTE)));
				
				time = (Calendar)c.clone();
				
				alarm = new Timer(1000, this);
				alarm.setActionCommand(AlarmClock.CMD_ALARM);
				alarm.start();
				
				if(options.getFrame().isVisible()) options.toggleSettings();
			}
		}
		else if( cmd.equals(AlarmClock.CMD_STOP) )
		{
			switch(state) {
			case AlarmClock.STATE_RUNNING:
				if(alarm != null) alarm.stop();
				
			default:
				state = AlarmClock.STATE_STOPPED;
				icon.setImage(AlarmIcon.getIcon());
				if(clip != null) clip.stop();
				icon.setToolTip(AlarmClock.STATUS_STOP);
			}
		}
		else if( cmd.equals(AlarmClock.CMD_ALARM) )
		{
			Calendar test = Calendar.getInstance();
			int hour = test.get(Calendar.HOUR_OF_DAY);
			int minute = test.get(Calendar.MINUTE);
			
			if(hour == time.get(Calendar.HOUR_OF_DAY) &&
					minute == time.get(Calendar.MINUTE))
			{
				alarm.stop();
				icon.setToolTip(AlarmClock.STATUS_STOP);
				options.toggleSettings();
				try {
					URL url = options.getSettings().getSound().toURI().toURL();
					clip = Applet.newAudioClip(url);
					clip.loop();
				}
				catch(java.net.MalformedURLException exception) {}
			}
		}
		else if( cmd.equals(AlarmClock.CMD_CHOOSE) )
		{
			JFileChooser choose = new AlarmFileChooser();
			int choice = choose.showOpenDialog(options.getFrame());
			if(choice == JFileChooser.APPROVE_OPTION)
			{
				File sound = choose.getSelectedFile();
				options.getSettings().setSound(sound);
				options.getFrame().setSound(sound);
			}
		}
	}
	
	//instance variables
	private Timer alarm;
	private Calendar time;
	private AudioClip clip;
	private AlarmMenu menu;
	private AlarmIcon icon;
	private AlarmOptions options;
	private int state;
	
	public static void main(String[] args) {
		new AlarmClock();
	}

}//end AlarmClock
